package nl.scalasim

import scala.actors.Actor

/** Harvester actor. */
class Harvester(name: String,
                val goods: String,
                val speed: Int,
                val capacity: Int) extends ScalasimActor(name) {

  private var producer: Actor = _
  private var harvestCalls = 0

  var stored = 0

  def connectTo(p: Actor): Harvester = {
    producer = p
    this
  }

  def act {
    loop {
      react (handleHarvest orElse handleDefault)
    }
  }

  /** Handler for Harvest messages. */
  def handleHarvest: PartialFunction[Any, Unit] = {
    case Harvest if producer == null => {
      warn("Not harvesting, no producer")
      reply(Harvested(goods, 0))
    }
    case Harvest if stored >= capacity => {
      warn("Not harvesting, capacity reached")
      reply(Harvested(goods, 0))
    }
    case Harvest if (harvestCalls + 1 < speed) => {
      harvestCalls += 1
      debug("Working...")
      reply(Harvested(goods, 0))
    }
    case Harvest => {
      val caller = sender
      harvestCalls = 0
      producer ! Produce
      react {
        case Produced(produced, amount) if produced != goods => {
          warn("Ignoring %d %s", amount, produced)
          caller ! Harvested(goods, 0)
        }

        case Produced(produced, amount) => {
          stored = (stored + amount) min capacity
          info("Harvested %d %s", amount, goods)
          caller ! Harvested(goods, amount)
        }
      }
    }
  }
}


